package com.yic.module.wms.job;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.yic.framework.common.util.collection.CollectionUtils;
import com.yic.framework.quartz.core.handler.JobHandler;
import com.yic.framework.tenant.core.job.TenantJob;
import com.yic.module.mes.api.plan.PlanApi;
import com.yic.module.mes.api.plan.dto.PlanRespDTO;
import com.yic.module.mes.api.report.ReportApi;
import com.yic.module.mes.api.report.dto.ReportRespDTO;
import com.yic.module.system.api.code.CodeApi;
import com.yic.module.system.enums.dict.ErpDocCodeEnum;
import com.yic.module.wms.controller.admin.erpproducein.vo.ErpProduceInCreateReqVO;
import com.yic.module.wms.service.erpproducein.ErpProduceInService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: Ljx
 * @createTime: 2023年12月26日 14:18:42
 * @version: v1.0.0
 * @Description: ERP生产完工入库单定时任务
 */

@Component
@Slf4j
public class ErpProduceInJob implements JobHandler {

    @Resource
    private ReportApi reportApi;
    @Resource
    private PlanApi planApi;
    @Resource
    private CodeApi codeApi;
    @Resource
    private ErpProduceInService erpProduceInService;

    /**
     * param参数解析：
     * param多参数通过|分割
     * 第一段：工厂
     * 第二段：生产车间
     * 第三段：时间范围（天）
     * @param param 参数
     * @return
     * @throws Exception
     */
    @TenantJob
    @Override
    public String execute(String param) throws Exception {
        String[] paramArr = param.split(",");
        Long factoryId = Long.valueOf(paramArr[0]);
        Long workshopId = Long.valueOf(paramArr[1]);
        Integer interval = Integer.valueOf(paramArr[2]);

        log.info("===工厂：{}车间{}开始执行ERP生产完工入库跑批", factoryId, workshopId);
        log.info("param={}", param);

        Date date = new Date();
        LocalDateTime endTime = DateUtil.endOfDay(date).toLocalDateTime();
        LocalDateTime startTime = DateUtil.beginOfDay(DateUtil.offsetDay(date, -interval)).toLocalDateTime();
        LocalDateTime[] timeArr = {startTime, endTime};
        List<ReportRespDTO> reportRespDTOList = reportApi.getReportList(factoryId, workshopId, timeArr);
        Map<Long, List<ReportRespDTO>> planMap = reportRespDTOList.stream().collect(Collectors.groupingBy(ReportRespDTO::getPlanId));
        List<String> codes = new ArrayList<>();
        for (Map.Entry<Long, List<ReportRespDTO>> entry: planMap.entrySet()) {
            // TODO 获取单号
            String code = codeApi.getCode("");
            Long planId = entry.getKey();
            List<ReportRespDTO> reportRespDTOS = entry.getValue();
            try {
                BigDecimal reportAmount = reportRespDTOS.stream().map(ReportRespDTO::getReportAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                List<Long> reportIds = CollectionUtils.convertList(reportRespDTOS, ReportRespDTO::getId);
                // 查询计划
                PlanRespDTO plan = planApi.getPlan(planId);
                ErpProduceInCreateReqVO reqVO = new ErpProduceInCreateReqVO();
                reqVO.setFactoryId(plan.getFactoryId());
                reqVO.setWorkshopId(plan.getWorkshopId());
                reqVO.setCode(code);
                reqVO.setErpDocCode(ErpDocCodeEnum.YG5A61.getErpDocCode());
                reqVO.setErpDocDate(LocalDateTime.now());
                reqVO.setErpCenterCode(plan.getErpCenterCode());
                reqVO.setErpWarehouseCode(plan.getErpWarehouseCode());
                reqVO.setPlanId(plan.getId());
                reqVO.setAcceptedQty(reportAmount);
                reqVO.setScrapQty(BigDecimal.ZERO);
                reqVO.setDestroyedQty(BigDecimal.ZERO);
                reqVO.setBatchNo(plan.getBatchNo());
                reqVO.setRemark(plan.getRemark());
                reqVO.setReportIds(reportIds);
                reqVO.setErpBinCode("");
                erpProduceInService.createErpProduceIn(reqVO);
            }catch (Exception e) {
                log.error(e.toString());
                continue;
            }
        }
        return String.format("生成入库单 %s 笔，入库清单：%s", codes.size(), String.join(",", codes));
    }
}
